option(BUILD_SHARED_LIBS "Build and use shared libraries" 0)
option(CREATE_COMPILATION_DATABASE_LINK "Create compilation database link. Implies CMAKE_EXPORT_COMPILE_COMMANDS" 1)

if (CREATE_COMPILATION_DATABASE_LINK)
    set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
endif ()

if (NOT DEFINED BAZEL_BIN)
    set(BAZEL_BIN "bazelisk")
endif ()

if (NOT DEFINED CODEQL_BAZEL_WORKSPACE)
    set(CODEQL_BAZEL_WORKSPACE "codeql")
endif ()

macro(bazel)
    execute_process(COMMAND ${BAZEL_BIN} ${BAZEL_STARTUP_OPTIONS} ${ARGN}
            COMMAND_ERROR_IS_FATAL ANY
            OUTPUT_STRIP_TRAILING_WHITESPACE
            WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
endmacro()

macro(bazel_even_if_failing)
    execute_process(COMMAND ${BAZEL_BIN} ${BAZEL_STARTUP_OPTIONS} ${ARGN}
            OUTPUT_STRIP_TRAILING_WHITESPACE
            WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
endmacro()

bazel(info workspace OUTPUT_VARIABLE BAZEL_WORKSPACE)
bazel(info output_base OUTPUT_VARIABLE BAZEL_OUTPUT_BASE)
set(BAZEL_EXEC_ROOT ${BAZEL_OUTPUT_BASE}/execroot/_main)
set(BAZEL_BUILD_OPTIONS --nocheck_visibility --keep_going)

macro(include_generated BAZEL_TARGET)
    bazel(build ${BAZEL_TARGET} ${BAZEL_BUILD_OPTIONS})
    string(REPLACE "@" "/external/" BAZEL_TARGET_PATH ${BAZEL_TARGET})
    string(REPLACE "//" "/" BAZEL_TARGET_PATH ${BAZEL_TARGET_PATH})
    string(REPLACE ":" "/" BAZEL_TARGET_PATH ${BAZEL_TARGET_PATH})
    include(${BAZEL_WORKSPACE}/bazel-bin${BAZEL_TARGET_PATH}.cmake)
endmacro()

macro(generate_and_include)
    file(REMOVE "${BAZEL_WORKSPACE}/.bazel-cmake/BUILD.bazel")
    # use aquery to only get targets compatible with the current platform
    bazel_even_if_failing(aquery "kind(\"cc_test|cc_binary\", ${ARGN})" ${BAZEL_BUILD_OPTIONS} --output=jsonproto OUTPUT_VARIABLE BAZEL_AQUERY_RESULT)
    string(JSON BAZEL_JSON_TARGETS GET "${BAZEL_AQUERY_RESULT}" targets)
    string(JSON LAST_IDX LENGTH "${BAZEL_JSON_TARGETS}")
    math(EXPR LAST_IDX "${LAST_IDX} - 1")
    foreach(IDX RANGE ${LAST_IDX})
        string(JSON CUR_BAZEL_TARGET GET "${BAZEL_JSON_TARGETS}" ${IDX} label)
        string(APPEND BAZEL_TARGETS "        '${CUR_BAZEL_TARGET}',\n")
    endforeach ()
    file(WRITE "${BAZEL_WORKSPACE}/.bazel-cmake/BUILD.bazel" "\
# this file was generated by cmake
load('@${CODEQL_BAZEL_WORKSPACE}//misc/bazel/cmake:cmake.bzl', 'generate_cmake')\n\
\n\
generate_cmake(\n\
    name = 'cmake',\n\
    testonly = True,\n\
    targets = [\n\
${BAZEL_TARGETS}\
    ],\n\
)\n")
    include_generated(//.bazel-cmake:cmake)
endmacro()

if (CREATE_COMPILATION_DATABASE_LINK)
    file(CREATE_LINK ${PROJECT_BINARY_DIR}/compile_commands.json ${PROJECT_SOURCE_DIR}/compile_commands.json SYMBOLIC)
endif ()
